// 基于下面提供的代码，完成后续的四个练习
const fp = require('lodash/fp');
class Container {
    static of(value) {
        return new Container(value);
    }

    constructor(value) {
        this._value = value;
    }

    map(fn) {
        return Container.of(fn(this._value));
    }
}
class Maybe {
    static of(x) {
        return new Maybe(x);
    }

    isNothing() {
        return this._value === null || this._value === undefined;
    }

    constructor(x) {
        this._value = x;
    }

    map(fn) {
        return this.isNothing() ? this : Maybe.of(fn(this._value));
    }
}

// 练习1：使用fp.add(x, y) 和 fp.map(f, x)创建一个能让functor里的值增加的函数ex1
let maybe = Maybe.of([5, 6, 1]);
let ex1 = (maybe) => {
    return maybe.map(arr => {
        return fp.map(x => {return fp.add(x, 1)}, arr)
    })
}
console.log('3-1输出结果为：');
console.log(ex1(maybe));

// 实现一个函数ex2，能够使用fp.first获取列表的第一个元素
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do']);
let ex2 = (xs) => {
    return xs.map(arr => {
        return fp.first(arr);
    })
}
console.log('3-1输出结果为：');
console.log(ex2(xs))

// 练习3：实现一个函数ex3，使用safeProp和fp.first找到user的名字的首字母
let safeProp = fp.curry(function(x,o) {
    return Maybe.of(o[x]);
})
let user = { id: 2, name: 'Alert' };
let ex3 = (user) => {
    return safeProp('name', user).map(res => {
        return fp.first(res);
    })
}
console.log('3-3输出结果为：')
console.log(ex3(user))

// 练习4：使用Maybe重写ex4，不要有if语句
let ex4 = function(n) {
    return Maybe.of(n).map(x => parseInt(x));
}
console.log('3-4输出结果为：')
console.log(ex4(3));
console.log(ex4());
